home *** CD-ROM | disk | FTP | other *** search
/ Hottest 6 / Hottest 6 (1996)(PDSoft)[!].iso / software / videoutils / h-m / mandelsquare / mandelsquare-1.06.lha / Double.c next >
C/C++ Source or Header  |  1992-12-20  |  12KB  |  495 lines

  1. /*
  2. **    MandelSquare - AmigaDOS 2.0/3.0 Mandelbrot set explorer
  3. **
  4. **    Double.c, Display double-buffering routines
  5. **
  6. **    Copyright © 1991-1992 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10.     /* Double buffering info. */
  11.  
  12. struct DBI
  13. {
  14.     struct Screen        *Screen,        /* Current display. */
  15.                 *NewScreen;        /* Local display. */
  16.     struct Window        *NewWindow;        /* Local window. */
  17.  
  18.     struct ScreenBuffer    *ScreenBuffer[2];    /* v39 double buffering info. */
  19.     struct MsgPort        *ScreenPort;        /* v39 double buffering sync port. */
  20.     struct BitMap        *UncompBitMap;        /* v39 uncompression bitmap */
  21.  
  22.     struct BitMap        *OriginalBitMap;    /* Old display bitmap. */
  23.  
  24.     struct Palette        *OriginalPalette;    /* Original display palette. */
  25.     struct Palette        *BlackPalette;        /* Paint it black. */
  26.  
  27.     struct BitMap        *BitMap[2];        /* v37 double buffering bitmaps. */
  28.  
  29.     struct timerequest    *TimeRequest;        /* Timer io for inter-frame delays. */
  30.     struct MsgPort        *TimePort;
  31. };
  32.  
  33.     /* Are we running under control of Kickstart 3.0 or higher? */
  34.  
  35. extern BYTE        Is39;
  36.  
  37.     /* Safe shared window closing routine. */
  38.  
  39. extern VOID        CloseWindowSafely(struct Window *Window);
  40.  
  41.     /* Bitmap allocation routines. */
  42.  
  43. extern VOID        FreeCustomBitMap(struct BitMap *BitMap,BYTE Standard);
  44. extern struct BitMap *    AllocCustomBitMap(UWORD Depth,UWORD Width,UWORD Height,BYTE Standard);
  45.  
  46.     /* Palette management. */
  47.  
  48. extern VOID        FreePalette(struct Palette *Palette);
  49. extern struct Palette *    AllocPalette(LONG NumColours,BYTE TrueColour);
  50. extern struct Palette *    GetPalette(struct Screen *Screen,struct Palette *Palette);
  51. extern VOID        LoadPalette(struct Screen *Screen,struct Palette *Palette,LONG NumColours);
  52. extern LONG        GetPaletteSize(struct Palette *Palette);
  53. extern BYTE        GetPaletteTriplet(struct Palette *Palette,UBYTE *Triplet,LONG Index);
  54. extern BYTE        SetPaletteTriplet(struct Palette *Palette,UBYTE R,UBYTE G,UBYTE B,LONG Index);
  55. extern ULONG        GetPaletteEntry(struct Palette *Palette,LONG Index);
  56. extern BYTE        SetPaletteEntry(struct Palette *Palette,ULONG Entry,LONG Index);
  57.  
  58.     /* Local routines. */
  59.  
  60. VOID            FreeDBI(struct DBI *Info);
  61. struct DBI *        AllocDBI(struct Screen *Screen);
  62. VOID            SwapDBI(struct DBI *Info,BYTE Copy);
  63. struct BitMap *        GetDBI(struct DBI *Info);
  64. VOID            PaletteDBI(struct DBI *Info,struct Palette *Palette);
  65. VOID            StartDBI(struct DBI *Info,ULONG Jiffies);
  66. VOID            WaitDBI(struct DBI *Info);
  67.  
  68.     /* FreeDBI(struct DBI *Info):
  69.      *
  70.      *    Free double-buffering information.
  71.      */
  72.  
  73. VOID
  74. FreeDBI(struct DBI *Info)
  75. {
  76.     WORD i;
  77.  
  78.         /* Release timer io request. */
  79.  
  80.     if(Info -> TimeRequest)
  81.     {
  82.         if(Info -> TimeRequest -> tr_node . io_Device)
  83.             CloseDevice(Info -> TimeRequest);
  84.  
  85.         DeleteIORequest(Info -> TimeRequest);
  86.     }
  87.  
  88.         /* Releae timer io reply port. */
  89.  
  90.     if(Info -> TimePort)
  91.         DeleteMsgPort(Info -> TimePort);
  92.  
  93.         /* Turn the screen black before we change
  94.          * the bitmap.
  95.          */
  96.  
  97.     if(Info -> BlackPalette && !Info -> NewScreen)
  98.     {
  99.         LoadPalette(Info -> Screen,Info -> BlackPalette,0);
  100.  
  101.         FreePalette(Info -> BlackPalette);
  102.     }
  103.  
  104.         /* Reinstall the original viewport bitmap. */
  105.  
  106.     if(Info -> OriginalBitMap)
  107.     {
  108.         Info -> Screen -> ViewPort . RasInfo -> BitMap = Info -> OriginalBitMap;
  109.  
  110.         MakeScreen(Info -> Screen);
  111.  
  112.         RethinkDisplay();
  113.     }
  114.  
  115.         /* Release the display bitmaps. */
  116.  
  117.     for(i = 0 ; i < 2 ; i++)
  118.     {
  119.         if(Info -> BitMap[i])
  120.             FreeCustomBitMap(Info -> BitMap[i],FALSE);
  121.     }
  122.  
  123.         /* Release the uncompression bitmap. */
  124.  
  125.     if(Info -> UncompBitMap)
  126.         FreeCustomBitMap(Info -> UncompBitMap,TRUE);
  127.  
  128.         /* Free the double-buffering information. */
  129.  
  130.     for(i = 0 ; i < 2 ; i++)
  131.     {
  132.         if(Info -> ScreenBuffer[i])
  133.             FreeScreenBuffer(Info -> NewScreen,Info -> ScreenBuffer[i]);
  134.     }
  135.  
  136.         /* Reset the screen palette. */
  137.  
  138.     if(Info -> OriginalPalette && !Info -> NewScreen)
  139.     {
  140.         LoadPalette(Info -> Screen,Info -> OriginalPalette,0);
  141.  
  142.         FreePalette(Info -> OriginalPalette);
  143.     }
  144.  
  145.         /* Release the double buffering sync port. */
  146.  
  147.     if(Info -> ScreenPort)
  148.         DeleteMsgPort(Info -> ScreenPort);
  149.  
  150.         /* Close the window if any. */
  151.  
  152.     if(Info -> NewWindow)
  153.         CloseWindowSafely(Info -> NewWindow);
  154.  
  155.         /* Bring the original screen to the front. */
  156.  
  157.     if(Info -> NewScreen)
  158.     {
  159.         ScreenToFront(Info -> Screen);
  160.  
  161.         CloseScreen(Info -> NewScreen);
  162.     }
  163.  
  164.         /* Free the info buffer. */
  165.  
  166.     FreeVec(Info);
  167. }
  168.  
  169.     /* AllocDBI(struct Screen *Screen):
  170.      *
  171.      *    Allocate double-buffering information handle.
  172.      */
  173.  
  174. struct DBI *
  175. AllocDBI(struct Screen *Screen)
  176. {
  177.     struct DBI *Info;
  178.  
  179.         /* Allocate the buffer. */
  180.  
  181.     if(Info = (struct DBI *)AllocVec(sizeof(struct DBI),MEMF_ANY | MEMF_CLEAR))
  182.     {
  183.         Info -> Screen = Screen;
  184.  
  185.             /* Get the screen palette. */
  186.  
  187.         if(Info -> OriginalPalette = GetPalette(Screen,NULL))
  188.         {
  189.                 /* Allocate blank palette. */
  190.  
  191.             if(Info -> BlackPalette = AllocPalette(GetPaletteSize(Info -> OriginalPalette),FALSE))
  192.             {
  193.                 BYTE Success;
  194.                 WORD i;
  195.  
  196.                     /* Are we running under control of
  197.                      * Kickstart 3.0 or higher?
  198.                      */
  199.  
  200.                 if(Is39)
  201.                 {
  202.                     struct Rectangle    DisplayClip;
  203.                     ULONG            Mode;
  204.  
  205.                         /* Just in case... */
  206.  
  207.                     Success = FALSE;
  208.  
  209.                         /* Obtain the main screen mode ID. */
  210.  
  211.                     Mode = GetVPModeID(&Screen -> ViewPort);
  212.  
  213.                         /* Query the overscan dimensions,
  214.                          * we wish to center the screen
  215.                          * on the display if possible.
  216.                          */
  217.  
  218.                     if(QueryOverscan(Mode,&DisplayClip,OSCAN_VIDEO))
  219.                     {
  220.                         LONG Differ;
  221.  
  222.                             /* Determine intervening space. */
  223.  
  224.                         Differ = ((DisplayClip . MaxX - DisplayClip . MinX + 1) - Screen -> Width) / 2;
  225.  
  226.                             /* Adjust position. */
  227.  
  228.                         DisplayClip . MinX += Differ;
  229.                         DisplayClip . MaxX -= Differ;
  230.  
  231.                             /* Open local screen,
  232.                              * don't mess with the
  233.                              * original screen.
  234.                              */
  235.  
  236.                         if(Info -> NewScreen = OpenScreenTags(NULL,
  237.                             SA_Width,    Screen -> Width,
  238.                             SA_Height,    Screen -> Height,
  239.                             SA_DClip,    &DisplayClip,
  240.                             SA_Left,    DisplayClip . MinX,
  241.                             SA_Depth,    Screen -> RastPort . BitMap -> Depth,
  242.                             SA_DisplayID,    Mode,
  243.                             SA_Font,    Screen -> Font,
  244.                             SA_ShowTitle,    FALSE,
  245.                             SA_Quiet,    TRUE,
  246.                             SA_AutoScroll,    TRUE,
  247.                             SA_Behind,    TRUE,
  248.                         TAG_END))
  249.                         {
  250.                             struct Window *Window = Screen -> FirstWindow;
  251.  
  252.                                 /* The simple way to make sure that
  253.                                  * the screen remains black.
  254.                                  */
  255.  
  256.                             LoadPalette(Info -> NewScreen,Info -> BlackPalette,0);
  257.  
  258.                                 /* Open a window our the local
  259.                                  * screen, just in case the user
  260.                                  * clicks the left mouse button.
  261.                                  */
  262.  
  263.                             if(Info -> NewWindow = OpenWindowTags(NULL,
  264.                                 WA_Width,    Screen -> Width,
  265.                                 WA_Height,    Screen -> Height,
  266.                                 WA_Borderless,    TRUE,
  267.                                 WA_Backdrop,    TRUE,
  268.                                 WA_RMBTrap,    TRUE,
  269.                                 WA_CustomScreen,Info -> NewScreen,
  270.                             TAG_DONE))
  271.                             {
  272.                                     /* Copy the input port. */
  273.  
  274.                                 Info -> NewWindow -> UserPort = Window -> UserPort;
  275.  
  276.                                     /* Install the standard main window IDCMP flags. */
  277.  
  278.                                 ModifyIDCMP(Info -> NewWindow,IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_MENUPICK | IDCMP_RAWKEY | IDCMP_VANILLAKEY | IDCMP_MENUVERIFY);
  279.  
  280.                                     /* Clear the mouse pointer. */
  281.  
  282.                                 SetPointer(Info -> NewWindow,Window -> Pointer,1,16,0,0);
  283.  
  284.                                     /* Create the sync port. */
  285.  
  286.                                 if(Info -> ScreenPort = CreateMsgPort())
  287.                                 {
  288.                                     Success = TRUE;
  289.  
  290.                                         /* Allocate the double-buffering
  291.                                          * information.
  292.                                          */
  293.  
  294.                                     for(i = 0 ; Success && i < 2 ; i++)
  295.                                     {
  296.                                         if(Info -> ScreenBuffer[i] = AllocScreenBuffer(Info -> NewScreen,NULL,(i ? NULL : SB_SCREEN_BITMAP)))
  297.                                         {
  298.                                             Info -> ScreenBuffer[i] -> sb_DBufInfo -> dbi_DispMessage . mn_ReplyPort = Info -> ScreenPort;
  299.  
  300.                                             BltBitMap(Screen -> RastPort . BitMap,0,0,Info -> ScreenBuffer[i] -> sb_BitMap,0,0,Info -> Screen -> Width,Info -> Screen -> Height,0xC0,0xFF,NULL);
  301.                                         }
  302.                                         else
  303.                                             Success = FALSE;
  304.                                     }
  305.  
  306.                                     if(Success)
  307.                                     {
  308.                                             /* Allocate the temporary bitmap
  309.                                              * data is to be uncompressed in.
  310.                                              */
  311.  
  312.                                         if(Info -> UncompBitMap = AllocCustomBitMap(Screen -> RastPort . BitMap -> Depth,Screen -> Width,Screen -> Height,TRUE))
  313.                                         {
  314.                                                 /* Bring the new screen to the front. */
  315.  
  316.                                             ScreenToFront(Info -> NewScreen);
  317.                                         }
  318.                                         else
  319.                                             Success = FALSE;
  320.                                     }
  321.                                 }
  322.                             }
  323.                         }
  324.                     }
  325.                 }
  326.                 else
  327.                 {
  328.                     Success = TRUE;
  329.  
  330.                         /* Allocate the double-buffering bitmaps. */
  331.  
  332.                     for(i = 0 ; Success && i < 2 ; i++)
  333.                     {
  334.                         if(!(Info -> BitMap[i] = AllocCustomBitMap(Screen -> RastPort . BitMap -> Depth,Screen -> Width,Screen -> Height,TRUE)))
  335.                             Success = FALSE;
  336.                     }
  337.                 }
  338.  
  339.                     /* Successful so far? */
  340.  
  341.                 if(Success)
  342.                 {
  343.                         /* Create the timer io reply port. */
  344.  
  345.                     if(Info -> TimePort = CreateMsgPort())
  346.                     {
  347.                             /* Create the timer io request. */
  348.  
  349.                         if(Info -> TimeRequest = (struct timerequest *)CreateIORequest(Info -> TimePort,sizeof(struct timerequest)))
  350.                         {
  351.                                 /* Open timer.device. */
  352.  
  353.                             if(!OpenDevice(TIMERNAME,UNIT_VBLANK,Info -> TimeRequest,0))
  354.                             {
  355.                                     /* Remember the original viewport bitmap. */
  356.  
  357.                                 if(!Is39)
  358.                                     Info -> OriginalBitMap = Screen -> ViewPort . RasInfo -> BitMap;
  359.  
  360.                                     /* Swap the on-screen bitmaps. */
  361.  
  362.                                 SwapDBI(Info,FALSE);
  363.  
  364.                                 return(Info);
  365.                             }
  366.                         }
  367.                     }
  368.                 }
  369.             }
  370.         }
  371.  
  372.         FreeDBI(Info);
  373.     }
  374.  
  375.     return(NULL);
  376. }
  377.  
  378.     /* SwapDBI(struct DBI *Info,BYTE Copy):
  379.      *
  380.      *    Swap the on-screen bitmaps.
  381.      */
  382.  
  383. VOID
  384. SwapDBI(struct DBI *Info,BYTE Copy)
  385. {
  386.         /* Pre-v39 double-buffering? */
  387.  
  388.     if(Info -> OriginalBitMap)
  389.     {
  390.         struct BitMap *Swap;
  391.  
  392.             /* Install the `hidden' bitmap. */
  393.  
  394.         Info -> Screen -> ViewPort . RasInfo -> BitMap = Swap = Info -> BitMap[0];
  395.  
  396.             /* Rebuild screen copper list. */
  397.  
  398.         MakeScreen(Info -> Screen);
  399.  
  400.         RethinkDisplay();
  401.  
  402.             /* Swap the bitmaps. */
  403.  
  404.         Info -> BitMap[0] = Info -> BitMap[1];
  405.         Info -> BitMap[1] = Swap;
  406.  
  407.             /* Copy the bitmap contents if necessary. */
  408.  
  409.         if(Copy)
  410.             BltBitMap(Info -> BitMap[1],0,0,Info -> BitMap[0],0,0,Info -> Screen -> Width,Info -> Screen -> Height,0xC0,0xFF,NULL);
  411.     }
  412.     else
  413.     {
  414.         struct ScreenBuffer *Swap;
  415.  
  416.             /* Blit the imagery to the hidden `bitmap'. */
  417.  
  418.         BltBitMap(Info -> UncompBitMap,0,0,Info -> ScreenBuffer[0] -> sb_BitMap,0,0,Info -> NewScreen -> Width,Info -> NewScreen -> Height,0xC0,0xFF,NULL);
  419.  
  420.             /* Install the hidden `bitmap'. */
  421.  
  422.         ChangeScreenBuffer(Info -> NewScreen,Swap = Info -> ScreenBuffer[0]);
  423.  
  424.             /* Swap the bitmaps. */
  425.  
  426.         Info -> ScreenBuffer[0] = Info -> ScreenBuffer[1];
  427.         Info -> ScreenBuffer[1] = Swap;
  428.  
  429.             /* Wait for bitmaps to get displayed. */
  430.  
  431.         WaitPort(Info -> ScreenPort);
  432.  
  433.         GetMsg(Info -> ScreenPort);
  434.  
  435.             /* Copy the bitmap contents if necessary. */
  436.  
  437.         if(Copy)
  438.             BltBitMap(Info -> ScreenBuffer[1] -> sb_BitMap,0,0,Info -> ScreenBuffer[0] -> sb_BitMap,0,0,Info -> NewScreen -> Width,Info -> NewScreen -> Height,0xC0,0xFF,NULL);
  439.     }
  440. }
  441.  
  442.     /* GetDBI(struct DBI *Info):
  443.      *
  444.      *    Obtain the currently `hidden' bitmap.
  445.      */
  446.  
  447. struct BitMap *
  448. GetDBI(struct DBI *Info)
  449. {
  450.     if(Info -> OriginalBitMap)
  451.         return(Info -> BitMap[0]);
  452.     else
  453.         return(Info -> UncompBitMap);
  454. }
  455.  
  456.     /* PaletteDBI(struct DBI *Info,struct Palette *Palette):
  457.      *
  458.      *    Set the new colour palette.
  459.      */
  460.  
  461. VOID
  462. PaletteDBI(struct DBI *Info,struct Palette *Palette)
  463. {
  464.     if(Info -> NewScreen)
  465.         LoadPalette(Info -> NewScreen,Palette,0);
  466.     else
  467.         LoadPalette(Info -> Screen,Palette,0);
  468. }
  469.  
  470.     /* StartDBI(struct DBI *Info,ULONG Jiffies):
  471.      *
  472.      *    Start frame delay counter (1 jiffy = 1/60 s).
  473.      */
  474.  
  475. VOID
  476. StartDBI(struct DBI *Info,ULONG Jiffies)
  477. {
  478.     Info -> TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  479.     Info -> TimeRequest -> tr_time . tv_secs    = Jiffies / 60;
  480.     Info -> TimeRequest -> tr_time . tv_micro    = ((Jiffies % 60) * 1000000) / 60;
  481.  
  482.     SendIO(Info -> TimeRequest);
  483. }
  484.  
  485.     /* WaitDBI(struct DBI *Info):
  486.      *
  487.      *    Wait for timer to elapse.
  488.      */
  489.  
  490. VOID
  491. WaitDBI(struct DBI *Info)
  492. {
  493.     WaitIO(Info -> TimeRequest);
  494. }
  495.